# -*- coding:utf-8 -*-
"""
查询图书
"""
import copy
import random
import logging
from datetime import datetime, timedelta
from typing import List


from LibrarySystem.repositories.sqlite3.models.book_models import Book
from LibrarySystem.repositories.sqlite3.RepositoryHelper import RepositoryHelper

from LibrarySystem.services.interface.query_service_interface import QueryServiceInterface

module_logger = logging.getLogger("logger")


class QueryService(QueryServiceInterface):
    """
    @ClassName：QueryService
    @Description： 继承 查询业务层 接口类，本项目只创建一个实例
    负责实现对书籍信息的查询功能
    该类大部分功能均使用多线程
    @Author：锦沐Python
    """
    def get_books_by_count(self, count: int):
        (flag, data) = RepositoryHelper.get_book_repository().get_books(count)
        return (flag, data)
    
    def get_books_by_keywords(self, keywords: str, user_id: str):
        """
        查询书籍信息
        @return:
        """
        # 截取前50条数据，防止渲染卡顿
        book_num = 50
        # 用于返回当前用户已借阅书籍
        borrowed_books = []
        filter_books = []
        # 定义一个包含需要检查字段的集合
        fields_to_check = ["book_name", "book_id", "category", "author"]

        (flag, book_list) = RepositoryHelper.get_book_repository().get_books_by_keywords(fields_to_check=fields_to_check, keywords=keywords)
        if flag is False:
            msg = book_list
            return (False, msg)

        # 将出借的图书放到最前面
        for book in book_list:
            if book.borrowed_by != "" and book.borrowed_by == user_id:
                borrowed_books.append(book)
                continue

            filter_books.append(book)

        random.shuffle(filter_books)
        all_books = borrowed_books + filter_books[:book_num]
        module_logger.info("图书匹配完成计算")

        return (True, all_books)


    def borrow_book(self, book_id: str, user_id: str):
        """
        查询书籍信息
        @return:
        """
        # 查找图书
        (flag, book) = RepositoryHelper.get_book_repository().query_book(book_id=book_id)

        if flag is False:
            msg = book
            module_logger.info(msg)
            return (flag, msg)

        borrow_book = Book()
        if book.borrowed_by == "":
            borrow_book = copy.deepcopy(book)
            borrow_book.borrowed_by = user_id
            borrow_book.borrow_time = datetime.now().strftime("%Y.%m.%d %H:%M:%S")
            # 设置归还时间（假设归还期限为借阅时间的10天后）
            borrow_time_dt = datetime.strptime(borrow_book.borrow_time, "%Y.%m.%d %H:%M:%S") + timedelta(
                days=borrow_book.loan_period)
            borrow_book.due_time = borrow_time_dt.strftime("%Y.%m.%d %H:%M:%S")

        (flag, msg) = RepositoryHelper.get_book_repository().update_book(borrow_book)
        if flag:
            module_logger.info(msg)
            return (True, msg)
        else:
            module_logger.info(msg)
            return (False, msg)


    def back_book(self, book_id: str, user_id: str):
        """
        查询书籍信息
        @return:
        """
        # 查找图书
        (flag, book) = RepositoryHelper.get_book_repository().query_book(book_id=book_id)
        if flag is False:
            msg = book
            module_logger.info(msg)
            return (flag, msg)

        back_book = Book()

        if book.borrowed_by == user_id:
            back_book = copy.deepcopy(book)
            back_book.borrowed_by = ""
            back_book.borrow_time = ""
            back_book.due_time = ""

        (flag, msg) = RepositoryHelper.get_book_repository().update_book(back_book)
        if flag:
            module_logger.info(msg)
            return (True, msg)
        else:
            module_logger.info(msg)
            return (False, msg)


    def sort_books(self, books: List[Book], type: str):
        """
        更具 最新上架时间，热度，数量，借阅状态进行筛选
        :param books:
        :param type: hot_up | hot_down | record_date_up | num_up | num_down | borrowed | un_borrowed
        """
        # 中文到英文的映射字典
        chinese_to_english = {
            "热度升序": "hot_up",
            "热度降序": "hot_down",
            "记录日期升序": "record_date_up",
            "数量升序": "num_up",
            "数量降序": "num_down",
            "已借出的": "borrowed",
            "未借出的": "un_borrowed"
        }

        sort_type = chinese_to_english[type]

        if sort_type == "hot_up" or sort_type == "hot_down":
            # 使用字典来统计每个 borrowed_counts 的数量，并同时存储对应的书籍列表
            borrowed_counts = {}
            for book in books:
                isbn = book.ISBN
                if book.borrowed_by and isbn in borrowed_counts:
                    borrowed_counts[isbn][0] += 1
                    borrowed_counts[isbn][1] = book
                else:
                    borrowed_counts[isbn] = [1, book]

            # 根据数量对ISBN进行排序（升序）
            if sort_type == "hot_up":
                sorted_isbns = sorted(borrowed_counts.items(), key=lambda x: x[1][0], reverse=True)
            else:
                sorted_isbns = sorted(borrowed_counts.items(), key=lambda x: x[1][0], reverse=False)
            # 构建排序后的书单，但每个ISBN只取一本书（这里取列表中的第一本）
            book_list = [book for _, (_, book) in sorted_isbns]

            return (True, book_list)

        if sort_type == "record_date_up":
            # 根据 record_time 字段对图书进行排序
            # 使用 lambda 函数将 record_time 字符串转换为 datetime 对象进行比较
            book_list = sorted(books,
                               key=lambda book: datetime.strptime(book.record_time, "%Y.%m.%d %H:%M:%S").timestamp(),
                               reverse=True)
            return (True, book_list)

        if sort_type == "num_up" or sort_type == "num_down":
            # 使用字典来统计每个ISBN的数量，并同时存储对应的书籍列表
            isbn_counts = {}
            for book in books:
                isbn = book.ISBN
                if isbn in isbn_counts:
                    isbn_counts[isbn][0] += 1
                    isbn_counts[isbn][1] = book
                else:
                    isbn_counts[isbn] = [1, book]

            # 根据数量对ISBN进行排序（升序）
            if sort_type == "num_up":
                sorted_isbns = sorted(isbn_counts.items(), key=lambda x: x[1][0], reverse=True)
            else:
                sorted_isbns = sorted(isbn_counts.items(), key=lambda x: x[1][0], reverse=False)
            # 构建排序后的书单，但每个ISBN只取一本书（这里取列表中的第一本）
            book_list = [book for _, (_, book) in sorted_isbns]

            return (True, book_list)

        if sort_type == "borrowed" or sort_type == "un_borrowed":
            book_list = []
            if sort_type == "borrowed":
                for book in books:
                    if book.borrowed_by:
                        book_list.append(book)
            else:
                for book in books:
                    if book.borrowed_by == "":
                        book_list.append(book)
            return (True, book_list)

        return (False, f"排序类型 {sort_type} 不存在")
    